import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import express from 'express';
import cron from 'node-cron';

// 配置部分
const config = {
    projectPath: 'C:\\Users\\li\\Desktop\\dkd-vue',
    giteeRepo: 'https://gitee.com/lixiongxiong/dkd-vue.git',
    branch: 'master',
    logFile: './modification_log.json',
    port: 3000,
    cronSchedule: '* * * * *',
    gitUserName: 'lixiongxiong',
    gitUserEmail: '178818915@qq.com'
};

// 修改方法集合
const modificationMethods = [
    (functionCode, functionName) => {
        const newParam = `newParam${Math.floor(Math.random() * 100)}`;
        return functionCode.replace(/(function\s+\w+\s*\([^)]*)/, `$1, ${newParam}`);
    },
    (functionCode, functionName) => {
        const vars = functionCode.match(/(let|const|var)\s+(\w+)/g) || [];
        if (vars.length > 0) {
            const randomVar = vars[Math.floor(Math.random() * vars.length)];
            const oldName = randomVar.split(/\s+/)[1];
            const newName = `renamed${Math.floor(Math.random() * 100)}`;
            return functionCode.replace(new RegExp(`\\b${oldName}\\b`, 'g'), newName);
        }
        return functionCode;
    },
    (functionCode, functionName) => {
        const lines = functionCode.split('\n');
        const insertIndex = Math.max(1, Math.floor(Math.random() * lines.length));
        lines.splice(insertIndex, 0, `    console.log("${functionName} executed");`);
        return lines.join('\n');
    }
];

// 日志系统
class Logger {
    constructor(logFile) {
        this.logFile = logFile;
        this.ensureLogFile();
    }

    ensureLogFile() {
        if (!fs.existsSync(this.logFile)) {
            fs.writeFileSync(this.logFile, JSON.stringify([], null, 2));
        }
    }

    log(operation, file, functionName, success = true, message = '') {
        const entry = {
            timestamp: new Date().toISOString(),
            operation,
            file,
            functionName,
            success,
            message
        };

        const logs = JSON.parse(fs.readFileSync(this.logFile, 'utf8'));
        logs.push(entry);
        fs.writeFileSync(this.logFile, JSON.stringify(logs, null, 2));
        console.log(`[${entry.timestamp}] ${operation} ${success ? 'SUCCESS' : 'FAILED'}: ${file} -> ${functionName} ${message}`);
    }

    getLogs(limit = 50) {
        const logs = JSON.parse(fs.readFileSync(this.logFile, 'utf8'));
        return logs.slice(-limit);
    }
}

// 主功能类
class CodeModifier {
    constructor(config) {
        this.config = config;
        this.logger = new Logger(config.logFile);
        this.lastRun = null;
        this.nextRun = null;
        this.isRunning = false;
        this.gitInitialized = false;
    }

    // 执行 Git 命令
    execGitCommand(command, options = {}) {
        try {
            return execSync(command, {
                cwd: this.config.projectPath,
                stdio: 'pipe',
                ...options
            }).toString().trim();
        } catch (error) {
            throw new Error(`Git command failed: ${command}\n${error.stderr?.toString() || error.message}`);
        }
    }

    // 初始化 Git 仓库
    async initializeGitRepository() {
        if (this.gitInitialized) return true;

        try {
            // 设置全局 Git 配置
            this.execGitCommand(`git config --global user.name "${this.config.gitUserName}"`);
            this.execGitCommand(`git config --global user.email "${this.config.gitUserEmail}"`);
            
            // 设置本地 Git 配置
            this.execGitCommand(`git config user.name "${this.config.gitUserName}"`);
            this.execGitCommand(`git config user.email "${this.config.gitUserEmail}"`);

            // 检查是否是 Git 仓库
            try {
                this.execGitCommand('git status');
                console.log('Git repository already exists');
            } catch {
                console.log('Initializing new Git repository...');
                this.execGitCommand('git init');
                this.execGitCommand(`git remote add origin ${this.config.giteeRepo}`);
            }

            // 检查分支
            const branches = this.execGitCommand('git branch');
            if (!branches.includes(this.config.branch)) {
                this.execGitCommand(`git checkout -b ${this.config.branch}`);
            } else {
                this.execGitCommand(`git checkout ${this.config.branch}`);
            }

            // 创建初始提交
            try {
                this.execGitCommand('git add .');
                this.execGitCommand('git commit -m "Initial commit by Auto Modifier"');
            } catch {
                // 如果已经有提交，忽略错误
            }

            this.gitInitialized = true;
            console.log('Git repository initialized successfully');
            return true;

        } catch (error) {
            console.error('Git initialization failed:', error.message);
            return false;
        }
    }

    // 查找所有代码文件
    findAllCodeFiles(dirPath, arrayOfFiles = []) {
        try {
            const files = fs.readdirSync(dirPath);
            files.forEach(file => {
                const fullPath = path.join(dirPath, file);
                try {
                    if (fs.statSync(fullPath).isDirectory()) {
                        if (!file.includes('node_modules') && !file.includes('.git')) {
                            this.findAllCodeFiles(fullPath, arrayOfFiles);
                        }
                    } else if (file.match(/\.(js|ts|vue)$/)) {
                        arrayOfFiles.push(fullPath);
                    }
                } catch (error) {
                    console.log(`Skipping ${fullPath}: ${error.message}`);
                }
            });
        } catch (error) {
            console.log(`Error reading directory ${dirPath}: ${error.message}`);
        }
        return arrayOfFiles;
    }

    // 从文件中提取函数
    extractFunctions(code, fileExt) {
        const functions = [];
        if (!code) return functions;

        try {
            const reservedKeywords = new Set(['if', 'for', 'while', 'switch', 'try', 'catch']);
            
            const functionRegex = /(function\s+(\w+)|(const|let|var)\s+(\w+)\s*=\s*(async\s*)?\s*function|(const|let|var)\s+(\w+)\s*=\s*\([^)]*\)\s*=>|(\w+)\s*\([^)]*\)\s*{)/g;
            let match;
            
            while ((match = functionRegex.exec(code)) !== null) {
                let functionName = match[2] || match[4] || match[7] || match[8];
                if (!functionName || reservedKeywords.has(functionName)) continue;
                
                const startPos = match.index;
                let braceCount = 0;
                let endPos = startPos;
                let foundStart = false;

                for (let i = startPos; i < Math.min(startPos + 1000, code.length); i++) {
                    if (code[i] === '{') {
                        braceCount++;
                        foundStart = true;
                    }
                    if (code[i] === '}') braceCount--;
                    if (foundStart && braceCount === 0) {
                        endPos = i;
                        break;
                    }
                }

                if (endPos > startPos) {
                    functions.push({
                        name: functionName,
                        code: code.substring(startPos, endPos + 1),
                        start: startPos,
                        end: endPos + 1
                    });
                }
            }
        } catch (error) {
            console.log('Error extracting functions:', error.message);
        }
        return functions;
    }

    // 生成随机函数名
    generateRandomFunctionName(originalName) {
        const prefixes = ['enhanced', 'modified', 'updated'];
        const suffixes = ['Handler', 'Function', 'Util'];
        return `${prefixes[Math.floor(Math.random() * prefixes.length)]}${originalName}${suffixes[Math.floor(Math.random() * suffixes.length)]}`;
    }

    // 执行修改
    async modifyAndCommit() {
        if (this.isRunning) return;
        this.isRunning = true;
        this.lastRun = new Date();

        try {
            console.log('Starting modification process...');

            // 初始化 Git
            if (!await this.initializeGitRepository()) {
                throw new Error('Git initialization failed');
            }

            // 查找代码文件
            const codeFiles = this.findAllCodeFiles(this.config.projectPath);
            if (codeFiles.length === 0) throw new Error('No code files found');

            // 选择文件和函数
            let functions = [];
            let randomFile = '';
            for (let i = 0; i < 3 && functions.length === 0; i++) {
                randomFile = codeFiles[Math.floor(Math.random() * codeFiles.length)];
                const fileContent = fs.readFileSync(randomFile, 'utf8');
                functions = this.extractFunctions(fileContent, path.extname(randomFile));
            }
            if (functions.length === 0) throw new Error('No functions found');

            const randomFunction = functions[Math.floor(Math.random() * functions.length)];
            const newFunctionName = this.generateRandomFunctionName(randomFunction.name);
            
            // 修改并写入文件
            const fileContent = fs.readFileSync(randomFile, 'utf8');
            const newFileContent = fileContent + `\n\n// Auto-generated function\n${randomFunction.code.replace(new RegExp(`\\b${randomFunction.name}\\b`, 'g'), newFunctionName)}`;
            fs.writeFileSync(randomFile, newFileContent);

            // Git 操作
            this.execGitCommand('git add .');
            this.execGitCommand(`git commit -m "Auto-modified: Added ${newFunctionName}"`);
            
            // 推送到远程
            try {
                this.execGitCommand(`git push -u origin ${this.config.branch}`);
            } catch {
                this.execGitCommand(`git push -f origin ${this.config.branch}`);
            }

            this.logger.log('Modification', path.basename(randomFile), randomFunction.name, true, `Added ${newFunctionName}`);
            console.log('Modification completed successfully!');

        } catch (error) {
            this.logger.log('Execution', 'System', 'N/A', false, error.message);
            console.error('Error:', error.message);
        } finally {
            this.isRunning = false;
        }
    }

    // 启动定时任务
    startScheduler() {
        console.log('Starting scheduler...');
        cron.schedule(this.config.cronSchedule, () => this.modifyAndCommit());
        this.startMonitorServer();
        setTimeout(() => this.modifyAndCommit(), 2000);
    }

    // 启动监控服务器
    startMonitorServer() {
        const app = express();
        app.get('/', (req, res) => {
            res.send(`
            <html><body>
                <h1>Code Modifier Monitor</h1>
                <p>Status: ${this.isRunning ? 'RUNNING' : 'IDLE'}</p>
                <p>Last Run: ${this.lastRun ? this.lastRun.toLocaleString() : 'Never'}</p>
            </body></html>
            `);
        });
        app.listen(this.config.port, () => {
            console.log(`Monitor server running on http://localhost:${this.config.port}`);
        });
    }
}

// 主程序
const modifier = new CodeModifier(config);
modifier.startScheduler();